package info.nightbrest.agt.shared.rpc.action;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONObject;
import info.nightbrest.agt.client.Agt;
import info.nightbrest.agt.client.AgtDispatcher;
import info.nightbrest.agt.client.AgtInjector;
import info.nightbrest.agt.shared.rpc.RpcParserException;
import info.nightbrest.agt.shared.rpc.SimpleStatus;
import info.nightbrest.agt.shared.rpc.transport.Serializer;

public abstract class AbstractAction<R extends AgtDispatcher.Result> implements AgtDispatcher.Action<R>
{
	private static AgtInjector injector = Agt.getApp().getInjector();

	protected JavaScriptObject requestData;
	protected String           requestUri;
	protected R                result;

	@Override
	public void init()
	{
	}

	@Override
	public String getRequestUri()
	{
		return requestUri;
	}

	@Override
	public void setRequestUri(String uri)
	{
		this.requestUri = uri;
	}

	@Override
	public RequestBuilder.Method getRequestMethod()
	{
		return RequestBuilder.POST;
	}

	@Override
	public String getPostData(AgtDispatcher.RpcDataFormat format) throws Exception
	{
		return injector.rpcSerializer().serialize(getRequestData(), format);
	}

	@Override
	public JavaScriptObject getRequestData()
	{
		return this.requestData;
	}

	@Override
	public void setRequestData(JavaScriptObject jso)
	{
		this.requestData = jso;
	}

	@Override
	public R getResult()
	{
		return result;
	}

	@Override
	public void setResult(R result)
	{
		this.result = result;
	}

	@Override
	public void onResponseReceived(Request request, Response response) throws RpcParserException
	{
		if (response.getStatusCode() == 200)
		{
			parseResponse(response.getText());
			return;
		}

		throw new RpcParserException(response.getStatusText());
	}

	protected void parseResponse(String responseText) throws RpcParserException
	{
		if (responseText.isEmpty())
		{
			throw new RpcParserException("Response is empty");
		}

		try
		{
			Serializer serializer = injector.rpcSerializer();
			JSONObject jsonObject = serializer.deserialize(responseText, AgtDispatcher.RpcDataFormat.DATA_JSON_FORMAT);

			result.setStatus(SimpleStatus.fromJSON(jsonObject));
			result.setData(jsonObject.getJavaScriptObject());
		}
		catch (Exception e)
		{
			throw new RpcParserException(e.getMessage());
		}
	}
}
